<?php

namespace App\Libs\Sms;

use api\utils\LogUtil;

class ChinaMobile
{
    // 'rspcod' => '说明',
    public static $errorMap = [
        'IllegalMac' => 'mac校验不通过。',
        'IllegalSignId' => '无效的签名编码。',
        'InvalidMessage' => '非法消息，请求数据解析失败。',
        'InvalidUsrOrPwd' => '非法用户名/密码。',
        'NoSignId' => '未匹配到对应的签名信息。',
        'success' => '数据验证通过。',
        'TooManyMobiles' => '手机号数量超限（>5000），应≤5000。',
    ];

    private $metaId;
    private $ecName; // 企业名称
    private $apId; // 接口账号用户名。
    private $secretKey;
    private $host = '112.35.1.155:1992';
    private $signature; // 短信签名
    private $serviceProvider = 'chinaMobile';
    private $sign; // 签名编码。在云MAS平台『管理』→『接口管理』→『短信接入用户管理』获取。
    private $addSerial; // 扩展码。依据申请开户的服务代码匹配类型而定，如为精确匹配，此项填写空字符串（""）；如为模糊匹配，此项可填写空字符串或自定义的扩展码，注：服务代码加扩展码总长度不能超过20位。

    public function getInstance($params)
    {
        $this->serviceProvider = 'chinaMobile';
        $this->metaId = $params['metaId'];
        !empty($params['ecName']) && $this->ecName = $params['ecName'];
        !empty($params['apId']) && $this->apId = $params['apId'];
        !empty($params['secretKey']) && $this->secretKey = $params['secretKey'];
        !empty($params['host']) && $this->host = $params['host'];
        !empty($params['signature']) && $this->signature = $params['signature'];
        !empty($params['sign']) && $this->sign = $params['sign'];
        !empty($params['addSerial']) && $this->addSerial = $params['addSerial'];

        return $this;
    }

    public function sendSms($phones, $params)
    {
        $sql = "select * from sms_template where id =
            (select outer_id from sms_template_config where service_provider = 'chinaMobile' and inner_id = " . $params['templateId'] . " and meta_id = " . $this->metaId . ")";
        $templates = Db::query($sql)->getResult();
        if (empty($templates) || empty($templates[0])) {
            LogUtil::warn('Component-Sms: china mobile template is empty try send by content. params: ' . json_encode($params));
            return $this->sendByContent($phones, $params);
        }

        return $this->sendByTemplate($phones, $params, $templates[0]);
    }

    private function sendByContent($phones, $params)
    {
        $content = strtr($params['content'], ['__SIGNATURE__' => $this->signature]);
        $postData = [
            'ecName' => $this->ecName,
            'apId' => $this->apId,
            'mobiles' => implode(',', $phones),
            'content' => $content,
            'sign' => $this->sign,
            'addSerial' => '',
        ];
        // 将ecName、apId、secretKey、mobiles、content、sign、addSerial按序拼接（无间隔符）成字符串
        $macStr = $postData['ecName'] . $postData['apId'] . $this->secretKey . $postData['mobiles'] . $postData['content'] . $postData['sign'] . $postData['addSerial'];
        $mac = md5($macStr);
        $postData['mac'] = $mac;

        $url = 'http://' . $this->host . '/sms/norsubmit';
        $response = $this->_curl($url, $postData);
        return $this->formatResponse($response, $params, $phones);
    }

    private function sendByTemplate($phones, $params, $template)
    {
        $tempParams = [];
        $postData = [
            'ecName' => $this->ecName,
            'apId' => $this->apId,
            'sign' => $this->sign,
            'templateId' => $template['template_id'],
            'mobiles' => implode(',', $phones),
            'params' => json_encode($tempParams),
            'addSerial' => '',
        ];
        $macStr = $postData['ecName'] . $postData['apId'] . '123qwe' . $postData['templateId'] . $postData['mobiles'] . $postData['params'] . $postData['sign'] . $postData['addSerial'];
        $mac = md5($macStr);
        $postData['mac'] = $mac;
        $postData['params'] = addslashes($params['params']);
        $url = 'http://' . $this->host . '/sms/tmpsubmit';
        $response = $this->_curl($url, $postData);

        return $this->formatResponse($response, $params, $phones);
    }

    private function _curl($url, $params, $headers = [])
    {
		$curl = curl_init();
	    curl_setopt($curl, CURLOPT_URL, $url);
	    curl_setopt($curl, CURLOPT_HEADER, 0);
	    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
	    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
	    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($curl, CURLOPT_POST, 1);//post提交方式
        curl_setopt($curl, CURLOPT_POSTFIELDS, base64_encode($params));
        curl_setopt($curl, CURLOPT_HTTPHEADER, ['Content-Type: application/json; charset=utf-8']);

	    $response = curl_exec($curl);
        LogUtil::warn('Component-Sms: -- curl china mobile -- url: ' . $url . ' response ' . $response . ' params ' . json_encode($params));
        curl_close($curl);

		return $response;
    }

    private function formatResponse($response, $params = [], $phones = [])
    {
        if (!empty($response) && is_string($response)) {
            $response = json_decode($response, true);
        }
        $log = [
            'service_provider' => 'chinaMobile',
            'params' => json_encode($params),
            'ref_id' => $params['recordIds'][0] ?? '',
            'template_id' => $params['outerId'] ?? '',
            'request_id' => $response['msgGroup'],
            'phone' => $phones[0] ?? '',
            'code' => empty($response['sucess']) ? 'failed' : 'OK',
            'message' => self::$errorMap[$response['rspcod']],
            'response' => json_encode($response),
        ];

        return [
            'items' => [$log],
            'requestId' => $response['msgGroup'],
        ];
    }
}
